package com.fxsh.learn.shiro;

import com.fxsh.learn.shiro.mapper.EmployeeMapper;
import com.fxsh.learn.shiro.mapper.PermissionMapper;
import com.fxsh.learn.shiro.mapper.RoleMapper;
import com.fxsh.learn.shiro.entity.Employee;
import com.fxsh.learn.shiro.entity.Role;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @Description 自定义Realm，从数据库获取信息
 * @Author Lrz
 * @date 2020/8/24 14:49
 */
@Slf4j
public class MyDBRealm extends AuthorizingRealm {
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
        // 获取用户角色信息
        List<Role> roleList = roleMapper.getRolesByEmpNo(employee.getEmpNo());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Set<String> roles = new HashSet<>();
        for (Role role : roleList){
            roles.add(role.getRoleName());
        }
        authorizationInfo.setRoles(roles);
        //获取用户权限信息
        List<String> permissions = permissionMapper.selectByRoles(roleList);
        authorizationInfo.setStringPermissions(new HashSet<String>(permissions));
        return authorizationInfo;
    }
    /**
     * @Description 自定义获取验证信息
     * @Param [authenticationToken]
     * @Return org.apache.shiro.authc.AuthenticationInfo
     * @Author Lrz
     * @date 2020/8/24 15:08
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 从token中获取传入的Principal（用户身份信息）
        String userName = (String)authenticationToken.getPrincipal();
        // 根据用户身份信息在数据库中查询用户信息的验证数据（密码）
        Map<String,Object> query = new HashMap<>();
        query.put("user_name",userName);
        List<Employee> emps = employeeMapper.selectByMap(query);
        if (emps == null || emps.size() == 0){
            return null;
        }
        Employee emp = emps.get(0);
        /*
        * 返回一个包含用户信息（可以是用户名或者是一个用户对象，作为Principal）、数据库中的验证数据的SimpleAuthenticationInfo对象
        * 这个对象会在后续的Credentials Matching（证书匹配）过程中将token中的credential和从数据库查到的credential进行对比
        * 匹配则验证成功，不匹配则验证失败
        * */
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(emp,emp.getPassword(),getName());
        return simpleAuthenticationInfo;
    }
}
